package mclight.selectors;
import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import mclight.containers.Container;
import mclight.Style;
import mclight.ValueComponent;

private enum SliderOrientation
{
	HORIZONTAL;
	VERTICAL;
}

class Slider extends ValueComponent
{
	inline public static var HORIZONTAL = SliderOrientation.HORIZONTAL;
	
	inline public static var VERTICAL = SliderOrientation.VERTICAL;
	
	var _orientation:SliderOrientation;
	
	public function new(
		orientation:SliderOrientation = null, ?parent:DisplayObjectContainer, ?container:Container, xpos:Float = 0, ypos:Float = 0,
		defaultHandler:Event->Dynamic = null
	)
	{
		_value = 0;
		_maxValue = 100;
		_minValue = 0;
		_orientation = orientation != null ? orientation : HORIZONTAL;
		super(parent, container, xpos, ypos);
		if(defaultHandler != null)
		{
			//addEventListener(Event.CHANGE, defaultHandler);
		}
	}
	
	override function init()
	{
		super.init();
		switch(_orientation)
		{
			case HORIZONTAL:
				setSize(100, 10);
			case VERTICAL:
				setSize(10, 100);
		}
	}
	
	var _handle:Sprite;
	
	var _back:Sprite;
	
	override function construct()
	{
		_back = new Sprite();
		_back.filters = [getComponentShadow(2, true)];
		_sprite.addChild(_back);
		
		_handle = new Sprite();
		_handle.filters = [getComponentShadow(1)];
		_handle.mouseEnabled = false;
		_handle.buttonMode = true;
		_handle.useHandCursor = true;
		_sprite.addChild(_handle);
		_back.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
	}
	
	function drawBack()
	{
		var g = _back.graphics;
		g.clear();
		g.beginFill(Style.BACKGROUND);
		g.drawRect(0, 0, _width, _height);
		g.endFill();
	}
	
	function drawHandle()
	{
		var g = _handle.graphics;
		g.clear();
		g.beginFill(Style.BUTTON_FACE);
		switch(_orientation)
		{
			case HORIZONTAL:
				g.drawRect(1, 1, _height - 2, _height - 2);
			case VERTICAL:
				g.drawRect(1, 1, _width - 2, _width - 2);
		}
		_handle.graphics.endFill();
		updateValueView();
	}
	
	override function updateValueView()
	{
		switch(_orientation)
		{
			case HORIZONTAL:
				var range = width - height;
				_handle.x = (_value - _minValue) / (_maxValue - _minValue) * range;
			case VERTICAL:
				var range = height - width;
				_handle.y = _height - _width - (_value - _minValue) / (_maxValue - _minValue) * range;
		}
	}
	
	function updateValueByHandle()
	{
		_value = switch(_orientation)
		{
			case HORIZONTAL: _handle.x / (width - height) * (_maxValue - _minValue) + _minValue;
			case VERTICAL: (_height - _width - _handle.y) / (height - width) * (_maxValue - _minValue) + _minValue;
		}
	}
	
	// PUBLIC METHODS
	
	public override function draw()
	{
		super.draw();
		drawBack();
		drawHandle();
	}
	
	public function setSliderParams(minValue:Float, maxValue:Float, value:Float)
	{
		this.minValue = minValue;
		this.maxValue = maxValue;
		this.value = value;
	}
	
	// HANDLERS
	
	function onMouseDown(event:MouseEvent)
	{
		if (!_handle.getBounds(_sprite).contains(_sprite.mouseX, _sprite.mouseY))
		{
			switch(_orientation)
			{
				case HORIZONTAL:
					var x = _sprite.mouseX - height / 2;
					x = Math.max(x, 0);
					x = Math.min(x, width - height);
					_handle.x = x;
				case VERTICAL:
					var y = _sprite.mouseY - width / 2;
					y = Math.max(y, 0);
					y = Math.min(y, height - width);
					_handle.y = y;
			}
			updateValueByHandle();
			//dispatchEvent(new Event(Event.CHANGE));
		}
		var stage = _sprite.stage;
		stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
		stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
		switch(_orientation)
		{
			case HORIZONTAL:
				_handle.startDrag(false, new Rectangle(0, 0, width - height, 0));
			case VERTICAL:
				_handle.startDrag(false, new Rectangle(0, 0, 0, height - width));
		}
	}
	
	function onMouseUp(event:MouseEvent)
	{
		var stage = _sprite.stage;
		stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
		stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
		_sprite.stopDrag();
	}
	
	function onMouseMove(event:MouseEvent)
	{
		var oldValue = _value;
		updateValueByHandle();
		if(_value != oldValue)
		{
			//dispatchEvent(new Event(Event.CHANGE));
		}
	}
	
	// PROPERTIES
}
